import { currentInstance, setCurrentInstace } from "./component";

const enum LifeCycleHooks {
  BEFORE_MOUNT = 'bm',
  MOUNTED = 'm',
  BEFORE_UPDATE = 'bu',
  UPDATED = 'u'
}

const injectHook = (type, hook, target) => {
  if (!target) {
    console.warn('injection APIs can only be used during execution setup().');
    return;
  }
  // 拿到用户的钩子里的回调函数，就是 onMounted(callback) 钩子中的 callback
  const hooks = target[type] || (target[type] = []);

  const wrap = () => {
    setCurrentInstace(target);
    hook.call(target);
    setCurrentInstace(null);
  }

  hooks.push(wrap);
}

const createHook = lifecycle => (hook, target = currentInstance) => { // target 挂载当前组件钩子的实例
  injectHook(lifecycle, hook, target);
}

/**
 * 执行用户的钩子函数中的回调函数
 * @param fns 用户的钩子函数的回调函数
 */
export const invokeArrayFns = fns => {
  for (let i = 0; i < fns.length; i++) {
    fns[i](); // 执行用户的钩子函数中的回调函数
  }
}

export const onBeforeMount = createHook(LifeCycleHooks.BEFORE_MOUNT);
export const onMounted = createHook(LifeCycleHooks.MOUNTED);
export const onBeforeUpdate = createHook(LifeCycleHooks.BEFORE_UPDATE);
export const onUpdated = createHook(LifeCycleHooks.UPDATED);